package com.asa.numanaly;

import com.asa.HanShu;
import com.asa.utils.MathUtils;

/**
 * 一元方程求解
 * @author Administrator
 *
 */
public class B {
	
	
	
	/**
	 * 二分法
	 * 
	 * p44
	 * 
	 * 
	 */
	public static Double zore1(HanShu hanshu,double a,double b) {
		int maxN0 = 1000;//最大迭代次数
		int i = 1;
		
		double FA = hanshu.hanshu(a);
		double TOL = 0.0001;
		
		
		while(i < maxN0) {
			
			
			double p = a+(b-a)/2;
			double FP = hanshu.hanshu(p);
			
			if (FP==0||(Math.abs(FP-0)<TOL)) {
				return p;
			}
			i++;
			if (FA*FP>0) {
				a=p;
				FA=FP;
			}else {
				b=p;
			}
			
		}

		return null;
	}
	
	
	
	
	
	/**
	 * 不动点迭代
	 * 
	 * p52
	 * 
	 * 
	 */
	public static Double zore2(HanShu hanshu,double p0) {
		int maxN0 = 1000;//最大迭代次数
		int i = 1;
		double TOL = 0.0001;
		while(i < maxN0) {	
			double p= hanshu.hanshu(p0);
			
			if (p==0||(Math.abs(p-p0)<TOL)) {
				return p;
			}
			i++;
			p0 = p;
		}
		return null;
	}
	
	
	/**
	 * 牛顿迭代法
	 * 
	 * p59
	 * 
	 * 
	 */
	public static Double zore3(HanShu hanshu,double p0) {
		int maxN0 = 10000;//最大迭代次数
		int i = 1;
		double TOL = 0.000001;
		while(i < maxN0) {	
			double p=p0 -  hanshu.hanshu(p0)/MathUtils.dao(p0, hanshu);
			
			if (p==0||(Math.abs(p-p0)<TOL)) {
				System.out.println(i);

				return p;
			}
			i++;
			p0 = p;
		}
		return null;
	}
	
	
	/**
	 * 正割法
	 * @param hanshu
	 * @param p0
	 * @return
	 */
	public static Double zore3_1(HanShu hanshu,double p0,double p1) {
		int maxN0 = 10000;//最大迭代次数
		int i = 1;
		double TOL = 0.000001;
		
		double q0 = hanshu.hanshu(p0);
		double q1 = hanshu.hanshu(p1);
		
		
		while(i < maxN0) {	
			double p= p1 - q1*(p1-p0)/(q1-q0);
			
			if (p==0||(Math.abs(p-p1)<TOL)) {
				System.out.println(i);

				return p;
			}
			i++;
			p0 = p1;
			q0 = q1;
			p1 = p;
			q1 = hanshu.hanshu(p);
			
			
			
			
			
		}
		return null;
	}
	
	/**
	 * 试位法
	 * @param hanshu
	 * @param p0
	 * @param p1
	 * @return
	 */
	public static Double zore3_2(HanShu hanshu,double p0,double p1) {
		int maxN0 = 10000;//最大迭代次数
		int i = 1;
		double TOL = 0.000001;
		
		double q0 = hanshu.hanshu(p0);
		double q1 = hanshu.hanshu(p1);
		
		
		while(i < maxN0) {	
			double p= p1 - q1*(p1-p0)/(q1-q0);
			
			if (p==0||(Math.abs(p-p1)<TOL)) {
				System.out.println(i);

				return p;
			}
			i++;
			
			double q = hanshu.hanshu(p);
			if (q*q1<0) {
				p0 = p1;
				q0=q1;
			}		
			p1 = p;
			q1 = q;
		
			
		}
		return null;
	}
	
	/**
	 * Steffensen方法	加速收敛
	 * p76
	 * 不动点迭代的一种
	 * @param hanshu
	 * @param p0
	 * @param p1
	 * @return
	 */
	public static Double zore5(HanShu hanshu,double p0,double p1) {
		int maxN0 = 10000;//最大迭代次数
		int i = 1;
		double TOL = 0.000001;
		
	
		
		
		while(i < maxN0) {	
			p1 = hanshu.hanshu(p0);
			double p2 = hanshu.hanshu(p1);
			
			double p = p0 - Math.pow(p1-p0,2)/(p2-2*p1+p0);
			if (p ==0 || Math.abs(p-p0)<TOL) {
				return p;
			}
			i++;
			p0 = p;
			
		}
		return null;
	}
	
	
	

	/**
	 * 多项式的零点
	 * Horner法		这个不是用来求0点的，而是用来求某个值以及在这点上多项式的导数
	 * 
	 * @param hanshu
	 * @param a	a1,a2,a3,...an
	 * @param x
	 * @return
	 */
	public static double[] zore6_1(double[] a,double x) {
		int maxN0 = 10000;//最大迭代次数
		double TOL = 0.000001;
		
		double y = a[a.length-1];
		double z = a[a.length-1];
		
		for (int j = a.length-2; j >0 ; j--) {
			
			y = x*y +a[j];
			z = x*z +y;
		}
		y = x*y+a[0];
		double[] result = new double[]{y,z};

		return result;
	}
	
	/**
	 * Muller法
	 * 
	 * 给的三个初始近似值，求零点
	 * p86
	 * @param hanshu
	 * @param x0
	 * @param x1
	 * @param x2
	 * @return
	 */
	public static Double zore6_2(HanShu hanshu,double x0,double x1,double x2) {
		int maxN0 = 10000;//最大迭代次数
		int i = 1;
		double TOL = 0.000001;
		double h1 = x1 -x0;
		double h2 = x2-x1;
		double o1 = (hanshu.hanshu(x1)-hanshu.hanshu(x0))/h1;
		double o2 = (hanshu.hanshu(x2)-hanshu.hanshu(x1))/h2;

		double d = (o1-o2)/(h2-h1);
		
		while(i<maxN0) {
			double b = o2 + h2*d;
			double D = Math.pow(b*b - 4* hanshu.hanshu(x2)*d, 0.5);//有可能是复数运算，所以说，这个我没写完
			double E = 1;
			if (Math.abs(b-D)<Math.abs(D-b)) {
				E = b+D;
			}else {
				E = b-D;
			}
			double h = -2*hanshu.hanshu(x2)/E;
			
			double p = x2+h;
			
			
			if (Math.abs(h)<TOL) {
				return p;
			}
			
			
			x0 = x1;
			x2=p;
			h1=x1-x0;
			h2 = x2-x1;
			o1 = (hanshu.hanshu(x1)-hanshu.hanshu(x0))/h1;
			o2 = (hanshu.hanshu(x2)-hanshu.hanshu(x1))/h2;
			d = (o1-o2)/(h2-h1);
			
			i++;
			
			
			
			
			
		}
		
		
		
		
		
		
		
		return null;

		
	}

	
	
	
	public static void main(String[] args) {
//		test2();
		
		
//		test3();

//		test3_1();
		
//		test3_2();
		
		HanShu hanshu = new HanShu() {
			
			@Override
			public double hanshu(double t, double x) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x0) {
				// TODO Auto-generated method stub
				
				
				return Math.pow(x0, 3)+4*Math.pow(x0, 2)-10;
//				return Math.pow(10-Math.pow(x0, 3), 0.5)/2;//不能直接使用函数本身，要把上一行的函数化成这一行这种形式
			}
		};
		
		double[] a = new double[]{-10.0,0.0,4.0,1.0};
		double[] zore6_1 = zore6_1(a, 1);
		
		System.out.println(zore6_1[0]+"  "+zore6_1[1]);
		
		
		System.out.println(hanshu.hanshu(1)+"   "+MathUtils.dao(1, hanshu));

		
	}





	





	private static void test3_2() {
		HanShu hanshu = new HanShu() {
			
			@Override
			public double hanshu(double t, double x) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x0) {
				// TODO Auto-generated method stub
				
				
				return Math.pow(x0, 3)+4*Math.pow(x0, 2)-10;
//				return Math.pow(10-Math.pow(x0, 3), 0.5)/2;//不能直接使用函数本身，要把上一行的函数化成这一行这种形式
			}
		};
		
		Double zore3_2 = zore3_2(hanshu , 1,10);
		System.out.println(zore3_2);
		
		System.out.println(hanshu.hanshu(zore3_2));
	}





	private static void test3_1() {
		HanShu hanshu = new HanShu() {
			
			@Override
			public double hanshu(double t, double x) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x0) {
				// TODO Auto-generated method stub
				
				
				return Math.pow(x0, 3)+4*Math.pow(x0, 2)-10;
//				return Math.pow(10-Math.pow(x0, 3), 0.5)/2;//不能直接使用函数本身，要把上一行的函数化成这一行这种形式
			}
		};
		
		Double zore3_1 = zore3_1(hanshu , 1,10);
		System.out.println(zore3_1);
		
		System.out.println(hanshu.hanshu(zore3_1));
	}





	private static void test3() {
		HanShu hanshu = new HanShu() {
			
			@Override
			public double hanshu(double t, double x) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x0) {
				// TODO Auto-generated method stub
				
				
				return Math.pow(x0, 3)+4*Math.pow(x0, 2)-10;
//				return Math.pow(10-Math.pow(x0, 3), 0.5)/2;//不能直接使用函数本身，要把上一行的函数化成这一行这种形式
			}
		};
		
		Double zore3 = zore3(hanshu , 1);
		System.out.println(zore3);
		
		System.out.println(hanshu.hanshu(zore3));
	}





	private static void test2() {
		HanShu hanshu = new HanShu() {
			
			@Override
			public double hanshu(double t, double x) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x0) {
				// TODO Auto-generated method stub
				
				
//				return Math.pow(x0, 3)+4*Math.pow(x0, 2)-10;
				return Math.pow(10-Math.pow(x0, 3), 0.5)/2;//不能直接使用函数本身，要把上一行的函数化成这一行这种形式
			}
		};
		
		Double zore3_1 = zore3_1(hanshu , 0,10);
		System.out.println(zore3_1);
	}





	private static void test1() {
		HanShu hanshu = new HanShu() {
			
			@Override
			public double hanshu(double t, double x) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x0) {
				// TODO Auto-generated method stub
				
				
				return x0-5;
			}
		};
		Double zore1 = zore1(hanshu , 0, 10);
		System.out.println(zore1);
	}
	
	
	
	
	
	
	
	
	
	
	

}
